#include "kinect_gui.h"
#include "ui_kinect_gui.h"

#define CHECK_RC(rc, what, flag)\
    flag= 1;\
    if (rc != XN_STATUS_OK)\
    {\
        qDebug() << what << "failed :"<< xnGetStatusString(rc);\
        flag = 0;\
    }\
     qDebug() << what << "succeed = " << flag;



KINECT_GUI::KINECT_GUI(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::KINECT_GUI)
{
    ui->setupUi(this);
    nRetVal = XN_STATUS_OK;
    depth_init =0;
    color_init =0;
    context_init =0;
    recorder_init =0;
    ui->bt_initialize_kinect->setEnabled(0);
    ui->bt_record->setEnabled(0);
}

KINECT_GUI::~KINECT_GUI()
{

    if(depth_init) depth.Release();
    if(color_init) color.Release();
    if(context_init) context.Release();


    delete ui;
}

void KINECT_GUI::on_bt_select_file_clicked()
{

    filename = QFileDialog::getSaveFileName(this, tr("Open File"),
                                            //QCoreApplication::applicationDirPath(),
                                            "/media/data/Dataset",
                                            tr("Oni Recording (*.oni)"));

    ui->bt_initialize_kinect->setEnabled(1);
    QStringList list1 = filename.split("/");
    QString temp = list1.last();
    qDebug()<<temp;
    ui->filename->setText(temp);

    ui->bt_initialize_kinect->setEnabled(1);

}

void KINECT_GUI::on_bt_initialize_kinect_clicked()
{

    // Initialize Context
    nRetVal = context.Init();
    CHECK_RC(nRetVal, "Kinect Initialization", context_init);


    // Intialize Depth
    nRetVal = depth.Create(context);
    CHECK_RC(nRetVal, "Depth Initialization",depth_init);


    // Intialize Color
    nRetVal = color.Create(context);
    CHECK_RC(nRetVal, "Color Initialization",color_init);

    // Intialize User
    nRetVal = user.Create(context);
    CHECK_RC(nRetVal, "Color Initialization",user_init);



    if(depth.IsCapabilitySupported("AlternativeViewPoint"))
    {
        nRetVal = depth.GetAlternativeViewPointCap().SetViewPoint(color);
        CHECK_RC(nRetVal,"Depth and Color Aligment",aligment);
    }
    else
    {
        qDebug()<< "Depth and Color aligment is  **** NOT **** possible";
    }

    // Creating Production Tree
    context.CreateAnyProductionTree(XN_NODE_TYPE_RECORDER,NULL,recorder)   ;
    CHECK_RC(nRetVal, "Create recorder",recorder_init);




    nRetVal = recorder.SetDestination(XN_RECORD_MEDIUM_FILE, filename.toAscii() );
    CHECK_RC(nRetVal, "Setting up recorder file ",recorder_file);

    nRetVal = recorder.AddNodeToRecording(depth, XN_CODEC_16Z_EMB_TABLES);
    CHECK_RC(nRetVal, "Adding Node to Recorder - Depth ",recorder_depth);

    nRetVal = recorder.AddNodeToRecording(color);
    CHECK_RC(nRetVal, "Adding Node to Recorder - Color ",recorder_color);

    nRetVal = context.StartGeneratingAll();
    CHECK_RC(nRetVal, "Kinect Final configuration ",startgeneration_init);
    qDebug()<< "Kinect is ready for Rock and Roll";


    if( startgeneration_init & recorder_init & recorder_file & recorder_depth  &\
            recorder_color & aligment &  user_init & color_init & depth_init &\
            context_init)
    {
         ui->bt_record->setEnabled(1);
    }
    else
    {

        if(depth_init) depth.Release();
        if(color_init) color.Release();
        if(context_init) context.Release();
        if(recorder_init) recorder.Release();


        int ret = QMessageBox::warning(this, tr("Recorder"),
                                           tr("Erro in Initialization\n"
                                              "Check Terminal for more information\n\n"),
                                           QMessageBox::Ok);
    }

}

void KINECT_GUI::on_bt_record_clicked()
{
    bool temp=0;
    unsigned int duration = ui->timeduration->time().toString("m").toDouble(&temp) * 60 + ui->timeduration->time().toString("ss").toDouble(&temp) ;
    n_frames = duration *30 ; // 30 FPS

    qDebug() << "Duration  = " << duration <<" seconds";
    qDebug() << "Number Of frames to be recorded = " << n_frames;

    ui->progressBar->setMaximum(n_frames);

    QTimer::singleShot(1000,this,SLOT(record_data()));
}

void KINECT_GUI::record_data()
{


    //    nRetVal = context.WaitOneUpdateAll();
    nRetVal = context.WaitAndUpdateAll();
    if (nRetVal != XN_STATUS_OK)
    {
        qDebug()<< "UpdateData Failed:"<<  xnGetStatusString(nRetVal); //fail ?
        QTimer::singleShot(20,this,SLOT(record_data())); //try again
        return;
    }

    depth.GetMetaData(depthMD);
    pDepthMap = depthMD.Data();

    color.GetMetaData(imageMD);
    pImageMap = color.GetRGB24ImageMap();

    qDebug()<< "Remaning Frame" << n_frames;

    recorder.Record();
    n_frames-=1;
    ui->progressBar->setValue(ui->progressBar->maximum() - (n_frames));
    if (n_frames)
    {
        QMetaObject::invokeMethod(this, "record_data",Qt::QueuedConnection);
    }
    else // last frame.
    {

        if(depth_init) depth.Release();
        if(color_init) color.Release();
        if(context_init) context.Release();
        if(recorder_init) recorder.Release();

        ui->bt_initialize_kinect->setEnabled(0);
        ui->bt_record->setEnabled(0);

        int ret = QMessageBox::information(this, tr("Recorder"),
                                           tr("The video recordind is finished\n "
                                              "If you want to record another video: restart the procedure\n\n"),
                                           QMessageBox::Ok);
    }
}
